package com.watson.retryer.service;

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

import java.time.LocalTime;

/**
 * @Description: TODO
 * @Author watson
 * @Date 2022/7/14 11:27
 * @Version 1.0
 */
@Service
public class RetryService {

//    @Autowired
//    private AccountFeignClient accountFeignClient;

    /**
     * Spring 系列的 spring-retry 是另一个实用程序模块，可以帮助我们以标准方式处理任何特定操作的重试。在 spring-retry 中，所有配置都是基于简单注释的。
     * <p>
     * value：抛出指定异常才会重试
     * include：和 value 一样，默认为空，当 exclude 也为空时，默认所有异常
     * exclude：指定不处理的异常
     * maxAttempts：最大重试次数，默认 3 次
     * backoff：重试等待策略，默认使用 @Backoff，@Backoff 的 value 默认为 1000L，我们设置为 2000L；multiplier（指定延迟倍数）默认为 0，表示固定暂停 1 秒后进行重试，如果把 multiplier 设置为 1.5，则第一次重试为 2 秒，第二次为 3 秒，第三次为 4.5 秒。
     *
     * @return
     */
//    @Retryable(maxAttempts = 3,backoff= @Backoff(value = 1000,multiplier = 1.5))
    @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier = 1.5))
    public int test(int code) throws Exception {
//    public BaseAccountResponse test() {
//        System.out.println("retry service test");
//        BaseAccountResponse baseAccountResponse = accountFeignClient.getAccount(729060943550464L).getBody();
//        return baseAccountResponse;

        System.out.println("test被调用,时间：" + LocalTime.now());
        if (code == 0) {
            throw new Exception("情况不对头！");
        }
        System.out.println("test被调用,情况对头了！");

        return 200;
    }

    /**
     * @return
     * @Retryable 重试失败后处理方法。如果不需要回调方法，可以直接不写回调方法，那么实现的效果是，重试次数完了后，如果还是没成功没符合业务判断，就抛出异常。
     * <p>
     * 可以看到传参里面写的是 Exception e，这个是作为回调的接头暗号（重试次数用完了，还是失败，我们抛出这个 Exception e 通知触发这个回调方法）。
     * <p>
     * 对于 @Recover 注解的方法，需要特别注意的是：
     * 方法的返回值必须与 @Retryable 方法一致
     * 方法的第一个参数，必须是 Throwable 类型的，建议是与 @Retryable 配置的异常一致，其他的参数，需要哪个参数，写进去就可以了（@Recover 方法中有的）
     * 该回调方法与重试方法写在同一个实现类里面
     * <p>
     * 作者：梅西爱骑车
     * 链接：https://www.jianshu.com/p/e51502612673
     * 来源：简书
     * 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
     */
    @Recover
    public int recover(Exception e, int code) {
//    public BaseAccountResponse testRetry() {
//        BaseAccountResponse baseAccountResponse = new BaseAccountResponse();
//        baseAccountResponse.setName("xxx");
//
//        return baseAccountResponse;

        System.out.println("回调方法执行！！！！");
        //记日志到数据库 或者调用其余的方法
        return 400;
    }
}
